package com.nbsaas.boot;

import com.baidu.aip.ocr.AipOcr;
import com.nbsaas.boot.rest.response.ResponseObject;
import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionRequest;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessage;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import com.volcengine.ark.runtime.service.ArkService;
import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * OCR和AI服务类
 * 提供OCR识别和AI纠错的统一接口
 * 引入智能策略优化处理流程
 */
public class OcrAiService {

    private AipOcr ocrClient;
    private ArkService aiService;
    private boolean isInitialized = false;

    // 策略配置 - 使用配置类中的参数

    /**
     * 初始化服务
     */
    public void initialize() {
        if (isInitialized) {
            return;
        }

        // 初始化百度OCR客户端
        ocrClient = new AipOcr(OcrConfig.BAIDU_APP_ID, OcrConfig.BAIDU_API_KEY, OcrConfig.BAIDU_SECRET_KEY);
        ocrClient.setConnectionTimeoutInMillis(OcrConfig.OCR_CONNECTION_TIMEOUT);
        ocrClient.setSocketTimeoutInMillis(OcrConfig.OCR_SOCKET_TIMEOUT);

        // 初始化火山引擎AI服务
        aiService = ArkService.builder()
                .dispatcher(Sample.dispatcher)
                .connectionPool(Sample.connectionPool)
                .apiKey(OcrConfig.VOLCENGINE_API_KEY)
                .build();

        isInitialized = true;
    }

    /**
     * 关闭服务
     */
    public void shutdown() {
        if (aiService != null) {
            aiService.shutdownExecutor();
        }
        isInitialized = false;
    }

    /**
     * 处理单张图片
     * @param imageUrl 图片URL
     * @return 处理结果
     */
    public ResponseObject<CallInfo> processImage(String imageUrl) {
        ResponseObject<CallInfo> result = new ResponseObject<>();

        if (!isInitialized) {
            initialize();
        }

        try {
            // 步骤1: OCR识别
            List<String> ocrWords = performOcrRecognition(imageUrl);
            System.out.println("OCR识别结果: " + ocrWords);

            if (ocrWords.isEmpty()) {
                return ResponseObject.error("OCR识别失败，未获取到任何文字");
            }

            // 步骤2: 使用正则提取器进行规则提取
            RegexExtractor extractor = new RegexExtractor();
            RegexExtractor.ExtractionResult extractionResult = extractor.extractWithConfigs(ocrWords);
            CallInfo ruleResult = extractionResult.getExtractedInfo();
            
            System.out.println("正则提取结果: " + ruleResult);
            System.out.println("匹配的正则模式: " + extractionResult.getMatchedPatterns());
            System.out.println("是否完整提取: " + extractionResult.isComplete());

            // 步骤3: 检查是否完整匹配，如果完整则直接返回，否则调用AI处理
            CallInfo finalResult;
            if (extractionResult.isComplete()) {
                System.out.println("正则提取完整匹配，直接返回结果");
                finalResult = ruleResult;
            } else {
                System.out.println("正则提取不完整，调用AI处理");
                finalResult = performAiCorrection(ocrWords);
                
                // 合并正则提取结果和AI结果
                finalResult = mergeResults(ruleResult, finalResult);
            }

            result.setData(finalResult);
        } catch (Exception e) {
            System.err.println("处理图片时发生错误: " + e.getMessage());
            e.printStackTrace();
            return ResponseObject.error("处理图片时发生错误");
        }

        return result;
    }

    /**
     * 批量处理图片
     * @param imageUrls 图片URL列表
     * @return 处理结果列表
     */
    public List<CallInfo> batchProcessImages(List<String> imageUrls) {
        List<CallInfo> results = new ArrayList<>();

        for (String imageUrl : imageUrls) {
            try {
                ResponseObject<CallInfo> result = processImage(imageUrl);
                if (result.getCode()==200){
                    results.add(result.getData());
                }
            } catch (Exception e) {
                System.err.println("处理图片 " + imageUrl + " 时发生错误: " + e.getMessage());
                results.add(new CallInfo());
            }
        }

        return results;
    }



    /**
     * 执行OCR识别
     * @param imageUrl 图片URL
     * @return 识别出的文字列表
     */
    private List<String> performOcrRecognition(String imageUrl) {
        try {
            JSONObject ocrResult = ocrClient.basicGeneralUrl(imageUrl, new HashMap<>());
            System.out.println("OCR原始结果: " + ocrResult.toString(2));

            // 检查OCR结果是否成功
            if (ocrResult.has("error_code")) {
                int errorCode = ocrResult.getInt("error_code");
                String errorMsg = ocrResult.optString("error_msg", "未知错误");
                System.err.println("OCR识别失败 - 错误码: " + errorCode + ", 错误信息: " + errorMsg);
                return new ArrayList<>();
            }

            // 检查是否有words_result字段
            if (!ocrResult.has("words_result")) {
                System.err.println("OCR结果中没有words_result字段，可能识别失败");
                System.err.println("OCR返回的所有字段: " + ocrResult.keySet());
                return new ArrayList<>();
            }

            JSONArray wordsResult = ocrResult.getJSONArray("words_result");
            List<String> words = new ArrayList<>();

            for (int i = 0; i < wordsResult.length(); i++) {
                JSONObject item = wordsResult.getJSONObject(i);
                if (item.has("words")) {
                    words.add(item.getString("words"));
                }
            }

            System.out.println("OCR识别到的文字数量: " + words.size());
            return words;

        } catch (Exception e) {
            System.err.println("OCR识别失败: " + e.getMessage());
            e.printStackTrace();
            return new ArrayList<>();
        }
    }



    /**
     * 使用AI进行纠错和优化
     * @param words OCR识别的文字列表
     * @return AI处理结果
     */
    private CallInfo performAiCorrection(List<String> words) {
        try {
            // 构建AI请求
            List<ChatMessage> messages = new ArrayList<>();
            messages.add(ChatMessage.builder()
                    .role(ChatMessageRole.SYSTEM)
                    .content(OcrConfig.AI_SYSTEM_PROMPT)
                    .build());

            messages.add(ChatMessage.builder()
                    .role(ChatMessageRole.USER)
                    .content("OCR识别内容: " + String.join(", ", words))
                    .build());

            ChatCompletionRequest request = ChatCompletionRequest.builder()
                    .model(OcrConfig.VOLCENGINE_MODEL)
                    .messages(messages)
                    .build();

            // 调用AI服务
            String aiResponse = aiService.createChatCompletion(request)
                    .getChoices()
                    .get(0)
                    .getMessage()
                    .getContent()
                    .toString();

            System.out.println("AI响应: " + aiResponse);

            // 解析AI返回的JSON
            return parseAiResponse(aiResponse);

        } catch (Exception e) {
            System.err.println("AI纠错失败: " + e.getMessage());
            return new CallInfo();
        }
    }

    /**
     * 解析AI返回的JSON响应
     * @param aiResponse AI返回的JSON字符串
     * @return 解析结果
     */
    private CallInfo parseAiResponse(String aiResponse) {
        CallInfo info = new CallInfo();

        try {
            // 尝试从AI响应中提取JSON
            String jsonStr = extractJsonFromResponse(aiResponse);
            if (jsonStr != null) {
                JSONObject json = new JSONObject(jsonStr);

                // 安全地提取phone字段
                if (json.has("phone") && !json.isNull("phone")) {
                    Object phoneObj = json.get("phone");
                    if (phoneObj != null) {
                        info.phone = phoneObj.toString();
                    }
                }

                // 安全地提取callTime字段
                if (json.has("callTime") && !json.isNull("callTime")) {
                    Object callTimeObj = json.get("callTime");
                    if (callTimeObj != null) {
                        info.callTime = callTimeObj.toString();
                    }
                }

                // 安全地提取duration字段，并确保格式为数字
                if (json.has("duration") && !json.isNull("duration")) {
                    Object durationObj = json.get("duration");
                    if (durationObj != null) {
                        String durationStr = durationObj.toString();
                        // 确保时长格式为数字
                        info.duration = normalizeDuration(durationStr);
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("解析AI响应失败: " + e.getMessage());
            System.err.println("AI响应内容: " + aiResponse);
        }

        return info;
    }

    /**
     * 从AI响应中提取JSON字符串
     * @param response AI响应
     * @return JSON字符串
     */
    private String extractJsonFromResponse(String response) {
        // 尝试找到JSON块
        int start = response.indexOf("{");
        int end = response.lastIndexOf("}");

        if (start != -1 && end != -1 && end > start) {
            return response.substring(start, end + 1);
        }

        return null;
    }

    /**
     * 标准化时长格式，确保为整型数字格式
     * @param durationStr 原始时长字符串
     * @return 标准化后的时长整型值
     */
    private Integer normalizeDuration(String durationStr) {
        if (durationStr == null || durationStr.trim().isEmpty()) {
            return null;
        }
        
        try {
            // 移除所有非数字字符，只保留数字
            String numbersOnly = durationStr.replaceAll("[^0-9]", "");
            
            if (numbersOnly.isEmpty()) {
                return null;
            }
            
            // 转换为整数，确保格式正确
            return Integer.parseInt(numbersOnly);
            
        } catch (NumberFormatException e) {
            System.err.println("时长格式转换失败: " + durationStr);
            return null;
        }
    }

    /**
     * 合并规则提取结果和AI纠错结果
     * @param ruleResult 规则提取结果
     * @param aiResult AI纠错结果
     * @return 合并后的结果
     */
    private CallInfo mergeResults(CallInfo ruleResult, CallInfo aiResult) {
        CallInfo finalResult = new CallInfo();

        // 优先使用AI结果，如果AI结果为空则使用规则结果
        finalResult.phone = (aiResult.phone != null) ? aiResult.phone : ruleResult.phone;
        finalResult.callTime = (aiResult.callTime != null) ? aiResult.callTime : ruleResult.callTime;
        // 确保时长格式为整型数字
        finalResult.duration = (aiResult.duration != null) ? aiResult.duration : ruleResult.duration;

        return finalResult;
    }


} 